//-----------------------------------------------------------------------
// <copyright file="Thread.cs" company="FreeToDev">(c) FreeToDev. This source is subject to the Microsoft Permissive License. See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. All other rights reserved.</copyright>
//-----------------------------------------------------------------------
namespace FreeToDev.MSBuildTasks.Misc
{
    using System.Globalization;
    using System.Threading;

    /// <summary>
    /// <b>Valid TaskActions are:</b>
    /// <para><i>Abort</i> (Warning: use only in exceptional circumstances to force an abort)</para>
    /// <para><i>Sleep</i> (<b>Required: </b> Timeout)</para>
    /// <para><i>SpinWait</i> (<b>Required: </b> Iterations)</para>
    /// <para><b>Remote Support:</b> NA</para>
    /// </summary>
    /// <example>
    /// <code><![CDATA[
    /// <Project ToolsVersion="3.5" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    ///     <PropertyGroup>
    ///         <TPath Condition="'$(TPath)' == ''">$(MSBuildProjectDirectory)\..\FreeToDev.MSBuild.tasks</TPath>
    ///         <TPath Condition="Exists('$(TPath)\..\..\Common\FreeToDev.MSBuild.tasks')">$(TPath)\..\..\Common\FreeToDev.MSBuild.tasks</TPath>
    ///     </PropertyGroup>
    ///     <Import Project="$(TPath)"/>
    ///   <Target Name="Default">
    ///     <FTDThread TaskAction="Sleep" Timeout="2000"/>
    ///     <FTDThread TaskAction="SpinWait" Iterations="1000000000"/>
    ///     <!--<FTDThread TaskAction="Abort"/>-->
    ///   </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>  
    public class FTDThread : FTDTaskBase
    {
        /// <summary>
        /// Number of millseconds to sleep for
        /// </summary>
        public int Timeout { get; set; }

        /// <summary>
        /// Number of iterations to wait for
        /// </summary>
        public int Iterations { get; set; }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            if (!this.TargetingLocalMachine())
            {
                return;
            }

            switch (this.TaskAction)
            {
                case "Abort":
                    this.Log.LogMessage("Aborting Current Thread");
                    Thread thisThread = Thread.CurrentThread;
                    thisThread.Abort();
                    break;
                case "Sleep":
                    this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Sleeping all threads for: {0}ms", this.Timeout));
                    Thread.Sleep(this.Timeout);
                    break;
                case "SpinWait":
                    this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "SpinWait all threads for: {0} iterations", this.Iterations));
                    Thread.SpinWait(this.Iterations);
                    break;
                default:
                    this.Log.LogError(string.Format(CultureInfo.InvariantCulture, "Invalid TaskAction passed: {0}", this.TaskAction));
                    return;
            }
        }
    }
}